import katex from 'katex';

class Vector extends Array{
  constructor(values, isColumn=false){
    super();

    if(values instanceof Array){
      for(let i = 0; i < values.length; i++){
        this.push( parseFloat(values[i]) );
      }
    }
    else{
      for(let i = 0; i < values; i++){
        this.push(0.00);
      }
    }

    this.isColumn = isColumn;

    this.decimals = 2; // 小数位数
  }

  // 点乘
  dot(vect){
    if( vect.length !== this.length ){
      return undefined;
    }

    var sum = 0.0;
    for(var i = 0, il = this.length; i < il; i++){
      sum += this[i] * vect[i];
    }

    return sum;
  }
  // 加
  add(vect){
    if( vect.length !== this.length ){
      return undefined;
    }

    var data = new Vector([], this.isColumn);

    for(var i = 0, il = this.length; i < il; i++){
      data[i]=(this[i] + vect[i]);
    }

    return data;
  }
  // 减
  sub(vect){
    if( vect.length !== this.length ){
      return undefined;
    }

    var data = new Vector([], this.isColumn);

    for(var i = 0, il = this.length; i < il; i++){
      data[i]=(this[i] - vect[i]);
    }

    return data;
  }
  // 数乘
  multiply(n){
    var data = new Vector([], this.isColumn);
    
    for(var i = 0, il = this.length; i < il; i++){
      data[i] = (n * this[i]);
    }

    return data;
  }
  // 获取指定位置的数据值
  get(index, fixed=false){
    if(fixed){
      return parseFloat(this[index].toFixed(this.decimals));
    }else{
      return this[index];
    }
  }

  set(...values){
    this.length = 0;
    for(var i = 0; i < values.length; i++){
      this.push(values[i]);
    }
  }

  // 复制向量
  copy(vect){
    this.length = 0;
    for(var i = 0; i < vect.length; i++){
      this.push(vect[i]);
    }
  }

  toString(){
    var str='(';
    for(var i = 0, il = this.length; i < il; i++){
      str += this[i].toFixed(this.decimals);
      if( i !== il - 1 ){
        str += ', ';
      }
    }
    str += ')';
    return str;
  }

  toKatexString(){
    var str='(';
    for(var i = 0, il = this.length; i < il; i++){
      str += this[i].toFixed(this.decimals);
      if( i !== il - 1 ){
        str += ', ';
      }
    }
    str += this.isColumn?')<sup>T</sup>':')';
    return str;
  }

  toHtmlString(withT=false){
    var str=this.toString();
    if(withT){
      str += this.isColumn?'<sup>T</sup>':'';
    }
    return str;
  }

  print(dom){
    if(!dom){
      console.log(this.toString());
    }
    else{
      katex.render(this.toKatexString(), dom, { throwOnError: false });
    }
  }
}

function calGramMatrix(vect){
  var G = [];
  for(var i = 0, il=vect.length; i < il; i++){
    var row = [];
    for(var j = 0, jl = vect.length; j < jl; j++){
      row.push(vect[i].dot(vect[j]));
    }
    G.push(row);
  }
  return G;
}

// 列表转向量
function toVector(arr, transpose=false){
  for(var i=0, il=arr.length; i<il; i++){
    arr[i] = new Vector(arr[i], transpose);
  }
  return arr;
}

// 渲染向量
function renderVectorsToDOM(element, vects){
  if(!element || !vects) return;
  let katexString = String.raw`\{`;
  for(let i = 0, il = vects.length; i < il; i++){
    katexString += vects[i].toKatexString();
    if(i !== il - 1){
      katexString += ',';
    }
  }
  katexString += String.raw`\}`;
  katex.render(katexString, element, { throwOnError: false });
}

export default Vector;
export {calGramMatrix, toVector, renderVectorsToDOM};